package com.huidu.bitrade.controller;

import com.alibaba.fastjson2.JSONObject;
import com.huidu.bitrade.constant.WithdrawStatus;
import com.huidu.bitrade.entity.Coin;
import com.huidu.bitrade.entity.Member;
import com.huidu.bitrade.entity.MemberWallet;
import com.huidu.bitrade.entity.WithdrawRecord;
import com.huidu.bitrade.hdwallet.CallBackDataRequest;
import com.huidu.bitrade.hdwallet.SignUtil;
import com.huidu.bitrade.hdwallet.data.CallbackData;
import com.huidu.bitrade.hdwallet.properties.HdWalletProperties;
import com.huidu.bitrade.service.*;
import com.huidu.bitrade.util.MessageResult;
import com.huidu.bitrade.vendor.provider.SMSProvider;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Collections;

@RestController
@RequestMapping("wallet")
@AllArgsConstructor
@Slf4j
public class HdWalletCallbackController {

    private final BiPayService biPayService;
    private final MemberWalletService walletService;
    private final WithdrawRecordService withdrawRecordService;
    private final CoinService coinService;
    private final MemberService memberService;
    private final SMSProvider smsProvider;
    private final HdWalletProperties hdWalletProperties;

    @PostMapping("/hd/notify")
    public synchronized String tradeCallback(@RequestBody CallBackDataRequest callBackDataRequest) throws Exception {
        log.info("收到回调：{}", callBackDataRequest.toString());
        boolean isOK = SignUtil.checkSign(hdWalletProperties.getApiKey(),
                callBackDataRequest.getTimestamp(),
                callBackDataRequest.getNonce(),
                callBackDataRequest.getBody(),
                callBackDataRequest.getSign());
        if (!isOK) {
            return "error";
        }
        String body = callBackDataRequest.getBody();
        CallbackData callbackData = JSONObject.parseObject(body, CallbackData.class);
        switch (callbackData.getTradeType()){
            case 1:
                recharge(body, callbackData);
                break;
            case 2:
                String error = withdraw(callbackData);
                if (error != null) return error;
                break;
        }
        return "success";
    }

    private String withdraw(CallbackData callbackData) {
        log.info("=====收到hd提币通知======");
        log.info("address:{},amount:{},coinType:{}", callbackData.getFromAddress(), callbackData.getAmount(), callbackData.getCoinType());
        String json = callbackData.getMeta();
        JSONObject jsonObject = JSONObject.parseObject(json);
        JSONObject data = jsonObject.getJSONObject("data");
        Long withdrawId = data.getLong("businessId");
        WithdrawRecord withdrawRecord = withdrawRecordService.findOne(withdrawId);
        if (withdrawRecord == null) {
            return "error";
        }
        //转账失败，状态变回等待放币
        if(callbackData.getStatus() == 1){
            log.info("转账中");
            if(withdrawRecord.getStatus() == WithdrawStatus.FAIL || withdrawRecord.getStatus() == WithdrawStatus.SUCCESS){
                return "error";
            }
            withdrawRecordService.withdrawSuccess(withdrawId, callbackData.getTxId());
        } else if (callbackData.getStatus() == 2) {
            log.info("提币失败");
            if(withdrawRecord.getStatus() == WithdrawStatus.FAIL || withdrawRecord.getStatus() == WithdrawStatus.SUCCESS){
                return "error";
            }
            withdrawRecordService.withdrawFail(withdrawId);
        }
        return null;
    }

    private void recharge(String body, CallbackData callbackData) {
        log.info("=====收到hd充币通知======");
        log.info("address:{},amount:{},coinType:{}", callbackData.getToAddress(), callbackData.getAmount(), callbackData.getCoinType());
        //金额为最小单位，需要转换,包括amount和fee字段
//        BigDecimal amount = callbackData.getAmount().divide(BigDecimal.TEN.pow(callbackData.getDecimals()),8, RoundingMode.DOWN);
        BigDecimal amount = callbackData.getAmount();

        String txId= callbackData.getTxId();
        String address = callbackData.getToAddress();
        String unit = biPayService.code2CoinByHd(callbackData.getCoinType());
        Coin coin = coinService.findByUnit(unit);
        log.info("=======充值unit:{}，查询数据对应coin:{}======",unit,coin);
        if (coin != null && walletService.findDeposit(address, txId) == null ) {
            log.info("=========调用充值service======coin:{},address:{},amount:{},txId:{}",coin,address,amount,txId);
            MessageResult mr = walletService.recharge(coin, address, amount, txId);
            log.info("wallet recharge result:{}", mr);
            if(mr.getCode()==0){
                MemberWallet wallet = walletService.findByCoinAndAddress(coin, address);
                Member mRes = memberService.findOne(wallet.getMemberId());
                try {
                    log.info("========开始发送短信======={}",mRes);
                    smsProvider.sendMessageByTempId(mRes.getMobilePhone(), Collections.singletonList("充值" + wallet.getCoin().getUnit() + "成功.充值数量为:" + amount.stripTrailingZeros().toPlainString()),2);
                } catch (Exception e) {
                    log.info("========发送短信异常======={}",mRes,e);
                }
            }
        }else {
            log.warn("未能入账{}" ,body);
        }
    }
}
